from django.http import Http404
from rest_framework import status
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import ListModelMixin
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView

from Person.authenticate import MyJSONWebTokenAuthentication
from Submission.models import Submission
from Submission.serializers import SubmissionSerializer, SubmissionListSerializer, SubmissionDetailListSerializer, \
    SubmissionStatusDetail
from Utils.BasePageNumberPagination import MyBasePageNumberPagination
from Utils.BaseResponse import BaseResponse
from Utils.GetUserFromToken import get_username_from_request


# Create your views here.
class SubmissionAPIView(APIView):
    """
    提供获取所有提交记录和添加新提交记录的功能
    """

    authentication_classes = [MyJSONWebTokenAuthentication]  # 登录认证
    permission_classes = [IsAuthenticated]  # 配置了权限类，没登录的就没有权限访问了

    def get(self, request, format=None):
        """
        获取所有已保存的提交记录
        :param request: HTTP请求对象
        :param format: 请求数据格式，默认为None
        :return: 返回包含所有提交记录数据的BaseResponse实例，状态码为HTTP_200_OK
        """
        submissions = Submission.objects.all()
        serializer = SubmissionSerializer(submissions, many=True)
        return BaseResponse(serializer.data, status=status.HTTP_200_OK).success()

    def post(self, request, format=None):
        """
        添加新的提交记录到数据库
        :param request: HTTP请求对象，其中包含待添加提交记录的数据
        :request.data 格式示例
        {
            "user": 11,
            "problem": 1,
            "contest": 5,
            "code": "又Debug完成了，好开行",
            "verdict": "AC",
            "lang": "C++",
            "time_cost": "0.01s",
            "memory_cost": "113k"
        }
        :return: 如果提交数据有效并成功保存，则返回新添加的提交记录数据，状态码为HTTP_201_CREATED；
                 否则返回错误信息及状态码HTTP_400_BAD_REQUEST
        """
        serializer = SubmissionSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return BaseResponse(serializer.data, status=status.HTTP_201_CREATED).success()
        return BaseResponse(serializer.errors, status=status.HTTP_400_BAD_REQUEST).fail("不合法的数据")


class SubmissionDetailAPIView(APIView):
    """
    提供对单个提交记录进行检索、更新和删除的功能
    """
    authentication_classes = [MyJSONWebTokenAuthentication]  # 登录认证
    permission_classes = [IsAuthenticated]  # 配置了权限类，没登录的就没有权限访问了

    def get_object(self, pk):
        try:
            return Submission.objects.get(pk=pk)
        except Submission.DoesNotExist:
            return Http404

    # GET方法：根据主键获取单个提交记录
    def get(self, request, pk, format=None):
        """
        获取指定主键的提交记录详情
        :param request: HTTP请求对象
        :param pk: 要获取的提交记录的主键
        :param format: 请求数据格式，默认为None
        :return: 如果找到指定主键的提交记录，则返回其序列化数据，状态码为HTTP_200_OK；
                 否则返回状态码为HTTP_404_NOT_FOUND的错误信息
        """
        try:
            submission = self.get_object(pk)
        except Http404:
            return BaseResponse(status=status.HTTP_404_NOT_FOUND).fail(f"对象不存在,不合法的 pk:{pk}")

        serializer = SubmissionSerializer(submission)
        return BaseResponse(serializer.data, status=status.HTTP_200_OK).success()

    def put(self, request, pk, format=None):
        """
        更新指定主键的提交记录
        :param request: HTTP请求对象，其中包含待更新的提交记录数据
        :param pk: 要更新的提交记录的主键
        :param format: 请求数据格式，默认为None
        :return: 如果数据有效并成功更新，则返回更新后的提交记录数据，状态码为HTTP_200_OK；
                 否则返回错误信息及状态码HTTP_400_BAD_REQUEST
        """
        try:
            submission = self.get_object(pk)
        except Http404:
            return BaseResponse(status=status.HTTP_404_NOT_FOUND).fail(f"对象不存在,不合法的 pk:{pk}")

        serializer = SubmissionSerializer(submission, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return BaseResponse(serializer.data, status=status.HTTP_200_OK).success()
        return BaseResponse(serializer.errors, status=status.HTTP_400_BAD_REQUEST).fail("不合法的数据")

    def delete(self, request, pk, format=None):
        """
        删除指定主键的提交记录
        :param request: HTTP请求对象
        :param pk: 要删除的提交记录的主键
        :param format: 请求数据格式，默认为None
        :return: 成功删除后，返回状态码为HTTP_204_NO_CONTENT的响应；
                若未找到对应提交记录，则返回状态码为HTTP_404_NOT_FOUND的错误信息
        """
        try:
            submission = self.get_object(pk)
        except Http404:
            return BaseResponse(status=status.HTTP_404_NOT_FOUND).fail(f"对象不存在,不合法的 pk:{pk}")

        submission.delete()
        return BaseResponse(status=status.HTTP_204_NO_CONTENT).success()


class SubmissionCheck(APIView):
    authentication_classes = [MyJSONWebTokenAuthentication]  # 登录认证
    permission_classes = [IsAuthenticated]  # 配置了权限类，没登录的就没有权限访问了

    def post(self, request, format=None):
        submission_id = request.data.get("id")
        if submission_id is None:
            return BaseResponse(status=status.HTTP_204_NO_CONTENT).fail("未传入 submission_id 值")
        try:
            submission = Submission.objects.get(id=submission_id)
        except Submission.DoesNotExist:
            return BaseResponse(status=status.HTTP_404_NOT_FOUND).fail("submission_id 值不存在")

        if submission.remote_id == "Submit Failed":
            return BaseResponse(data={"status": "Submit Failed", "result": "Submit Failed"},
                                status=status.HTTP_400_BAD_REQUEST).fail(submission.additional_info)

        serializer = SubmissionListSerializer(submission)
        return BaseResponse(data={"status": submission.verdict, "result": serializer.data},
                            status=status.HTTP_200_OK).success()

    def get_object(self, pk):
        try:
            return Submission.objects.get(pk=pk)
        except Submission.DoesNotExist:
            return Http404

    def get(self, request, pk, format=None):
        try:
            submission = self.get_object(pk)
        except Http404:
            return BaseResponse(status=status.HTTP_404_NOT_FOUND).fail(f"提交不存在,不合法的 id:{pk}")

        serializer = SubmissionStatusDetail(submission)
        return BaseResponse(serializer.data, status=status.HTTP_200_OK).success()


class ListUserSubmission(APIView):
    authentication_classes = [MyJSONWebTokenAuthentication]  # 登录认证
    permission_classes = [IsAuthenticated]  # 配置了权限类，没登录的就没有权限访问了

    def post(self, request, format=None):
        problem_id = request.data.get("problemId")
        username = get_username_from_request(request.headers.get('Authorization'))

        if problem_id is None:
            return BaseResponse(status=status.HTTP_400_BAD_REQUEST).fail("未传入题目ID")
        if username is None:
            return BaseResponse(status=status.HTTP_400_BAD_REQUEST).fail("未传入用户名")

        try:
            submissions = Submission.objects.filter(problem__id=problem_id, user__username=username).order_by(
                'submission_time')
        except Submission.DoesNotExist:
            return BaseResponse(status=status.HTTP_404_NOT_FOUND).fail("提交记录为空")

        serializer = SubmissionDetailListSerializer(submissions, many=True)
        #        print(serializer.data)

        return BaseResponse(data=serializer.data, status=status.HTTP_200_OK).success()


class ListSubmission(GenericAPIView, ListModelMixin):
    authentication_classes = [MyJSONWebTokenAuthentication]  # 登录认证
    permission_classes = [IsAuthenticated]  # 配置了权限类，没登录的就没有权限访问了

    queryset = Submission.objects.all().order_by('-submission_time')
    serializer_class = SubmissionDetailListSerializer
    pagination_class = MyBasePageNumberPagination  # 使用分页器

    def get(self, request, format=None):
        res = self.list(request, format)

        if res.status_code == status.HTTP_200_OK:
            return BaseResponse(res.data, status=status.HTTP_200_OK).success()
        return BaseResponse(data=res.data, status=res.status_code).fail()
